/*
 *  Copyright 2001-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package ar.uba.fi.posgrado.common.dao;

import java.util.List;

import org.hibernate.criterion.Criterion;
import org.hibernate.exception.ConstraintViolationException;

import ar.uba.fi.posgrado.common.exception.MissingArgumentException;
import ar.uba.fi.posgrado.common.model.AbstractDomainObject;

/**
 * Interfaz que debera ser implementada por cada una de las implementacion de
 * los DAOs Provee los metodos basicos de trabajo con datos.
 * 
 * @author nicolas.gonzalez
 */
public interface GenericDAO<T> {

	/**
	 * Busca una instancia por PK.
	 * 
	 * @param id
	 *            Id a buscar
	 * @return Devuelve la instancia encontrada
	 * @throws MissingArgumentException
	 *             En caso de recibir null
	 * @throws NoSuchEntityException
	 *             En caso de no encontrar la instancia del id en cuestion
	 * @throws DAOException
	 *             Error de conexion o SQL
	 */
	public AbstractDomainObject findById(Long id)
			throws MissingArgumentException, NoSuchEntityException,
			DAOException;

	/**
	 * Persiste la instancia
	 * 
	 * @param object
	 *            Instancia a persistir
	 * @return Devuelve el Id de la instancia
	 * @throws MissingArgumentException
	 *             En caso de recibir null
	 * @throws DAOException
	 *             Error de conexion o SQL
	 */
	public Long save(AbstractDomainObject object)
			throws MissingArgumentException, DAOException;

	/**
	 * Persiste una instancia modificada
	 * 
	 * @param object
	 *            Instancia a 'updatear'
	 * @throws MissingArgumentException
	 *             En caso de recibir null
	 * @throws DAOException
	 *             Error de conexion o SQL
	 */
	public void update(AbstractDomainObject object)
			throws MissingArgumentException, DAOException;

	/**
	 * Remueve una instancia
	 * 
	 * @param object
	 *            Objecto a remover
	 * @throws MissingArgumentException
	 *             En caso de recibir null
	 * @throws DAOException
	 *             Error de conexion o SQL
	 */
	public void remove(AbstractDomainObject object)
			throws MissingArgumentException, DAOException, ConstraintViolationException;

	/**
	 * Busca todas las instancias del tipo T
	 * 
	 * @return lista de todos los objetos de la clase correspondiente
	 * @throws MissingArgumentException
	 *             Devuelve en un List las instancias encontradas
	 * @throws DAOException
	 *             Error de conexion o SQL
	 */
	public List<T> findAll() throws MissingArgumentException, DAOException;

    /**
     * Busca todas las instancias del tipo T aplicando una serie
     * de Criterions.<br>
     *
     * @param criterions {@link List} de {@link Criterion}s.<br> 
     * @return lista de todos los objetos de la clase correspondiente
     * @throws MissingArgumentException
     *             Devuelve en un List las instancias encontradas
     * @throws DAOException
     *             Error de conexion o SQL
     */
	public List<T> findByCriterions(final List<Criterion> criterions) throws DAOException;
	
	/**
	 * Genera un Sufijo para los campos marcados como borrados.<br>
	 * @return Devuelve un String q siempre sera el mismo para toda la aplicacion.<br>
	 */
	public String generateRemovedSufix();
	
}
